#include "../import/head.h"
#include "helper_tcp.h"
#include "../data_struct/head.h"
#include "../global/head.h"
#include "../macro/head.h"
#include "../msg/head.h"
#include "../helper_package/head.h"
#include "../helper_net/head.h"

namespace xos_sgsj
{

    helper_tcp::helper_tcp()
    {
    }

    helper_tcp::~helper_tcp()
    {
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // proc

    int helper_tcp::proc( data * pData )
    {
        int ret = 0;

        int nMsg = pData->m_nMsg;

        switch( nMsg )
        {
        case MSG_TCP_INIT:
            {
                ret = on_init( pData );
            }
            break;
        case MSG_TCP_ACCEPT:
            {
                ret = on_accept( pData );
            }
            break;
        case MSG_TCP_CONNECT:
            {
                ret = on_connect( pData );
            }
            break;
        case MSG_TCP_RECV:
            {
                ret = on_recv( pData );
            }
            break;
        case MSG_TCP_SEND:
            {
                ret = on_send( pData );
            }
            break;
        case MSG_TCP_NEED_CLOSE:
            {
                ret = need_close( pData );
            }
            break;
        case MSG_TCP_CLOSE:
            {
                ret = on_close( pData );
            }
            break;
        default:
            {
                ret = 1;
            }
            break;
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int helper_tcp::on_init( data * pData )
    {
        int ret = 0;

        tcp * pTcp = pData->m_pTcp;
        session * pSession = pTcp->m_pSession;

        if( ( 0 == ret ) && !pData->m_bSuccess )
        {
            pSession->release();
            pSession = 0;
            pTcp->release();
            pTcp = 0;
            ret = 1;
        }

        if( 0 == ret )
        {
            pSession->init_add_ref( 1 );
        }

        if( ( 0 == ret ) && ( session::TYPE_TCP_LISTEN == pSession->m_eType ) )
        {
            data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
            p->init();
            p->m_bSuccess = pData->m_bSuccess;
            p->m_nMsg = MSG_TCP_STARTED;
            g_pSysData->notify( p );
        }

        return ret;
    }

    int helper_tcp::on_accept( data * pData )
    {
        int ret = 0;

        tcp * pTcp = pData->m_pTcp;
        session * pSession = pTcp->m_pSession;

        if( ( 0 == ret ) && !pData->m_bSuccess )
        {
            ret = 1;
        }

        if( 0 == ret )
        {
            pSession->init_add_ref( 1 );
        }

        if( ( 0 == ret ) && ( session::TYPE_TCP_LISTEN == pSession->m_eType ) )
        {
            pSession->m_eType = session::TYPE_TCP_DATA;
        }

        return ret;
    }

    int helper_tcp::on_connect( data * pData )
    {
        int ret = 0;

        tcp * pTcp = pData->m_pTcp;
        session * pSession = pTcp->m_pSession;

		if( ( 0 == ret ) && pData->m_bSuccess )
		{
			pSession->init_add_ref( 1 );
		}
        
		if( ( 0 == ret ) && !pData->m_bSuccess )
        {
            pSession->release();
            pSession = 0;
            pTcp->release();
            pTcp = 0;
            ret = 1;
        }

		if( 0 == ret )
		{
			data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
			p->init();
			p->m_bSuccess = pData->m_bSuccess;
			p->m_nMsg = MSG_TCP_STARTED;
			p->m_pSession = pSession;
			p->m_pTcp = pTcp;
			g_pSysData->notify( p );
		}

        return ret;
    }

    int helper_tcp::on_recv( data * pData )
    {
        int ret = 0;

        xos::i_buf * pBuf = pData->m_pBuf;
        pData->m_pBuf = 0;
        tcp * pTcp = pData->m_pTcp;
        session * pSession = pTcp->m_pSession;
        session::ref ref( pSession, 1 );

        if( ( 0 == ret ) && ( !pData->m_bSuccess || ( 0 != ref.is_added() ) ) )
        {
            ret = 1;
        }

        if( ( 0 == ret ) && ( session::TYPE_TCP_DATA == pSession->m_eType ) )
        {
			helper_package obj;
			ret = obj.on_recv( pBuf, pData );
            pBuf = 0;
        }

        if( pBuf )
        {
            pBuf->release();
            pBuf = 0;
        }

        return ret;
    }

    int helper_tcp::on_send( data * pData )
    {
        int ret = 0;

        xos::i_buf * pBuf = pData->m_pBuf;

        if( pBuf )
        {
            pBuf->release();
            pBuf = 0;
        }

        return ret;
    }

    int helper_tcp::need_close( data * pData )
    {
        int ret = 0;

        tcp * pTcp = pData->m_pTcp;
        session * pSession = pTcp->m_pSession;

        if( 0 == ret )
        {
            ret = pSession->sub_ref( 1 );
        }

        return ret;
    }

    int helper_tcp::on_close( data * pData )
    {
        int ret = 0;

        tcp * pTcp = pData->m_pTcp;
        session * pSession = pTcp->m_pSession;

        pSession->release();
        pSession = 0;
        pTcp->release();
        pTcp = 0;

        return ret;
    }

} // xos_sgsj
